<template>
    <div :style="{ width, height }">
        <a-upload
            :auto-upload="false"
            :file-list="fileList"
            :show-file-list="false"
            :accept="accept"
            disabled
            class="w-full h-full"
        >
            <template #upload-button>
                <a-popover :unmount-on-close="false" :disabled="fileList.length > 0">
                    <div
                        :class="borderColor"
                        class="w-full h-full bg-[#18191c] rounded-md p-2 flex flex-col items-center justify-center cursor-pointer relative group"
                    >
                        <div v-if="!loading" class="w-full h-full flex flex-col items-center justify-center">
                            <!-- 已上传媒体的预览 -->
                            <div v-if="fileList.length > 0" class="absolute inset-0 w-full h-full">
                                <div class="relative w-full h-full group">
                                    <!-- 图片预览 -->
                                    <img 
                                        v-if="type === 'image'" 
                                        :src="fileList[0].url" 
                                        class="w-full h-full object-contain"
                                    />
                                    <!-- 视频预览 -->
                                    <video
                                        v-else
                                        :src="fileList[0].url"
                                        class="w-full h-full object-contain"
                                    />
                                    <!-- 悬停操作区 -->
                                    <div class="absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center gap-4">
                                        <div class="text-white cursor-pointer rounded-full p-2 bg-teal-600" @click.stop="previewMedia">
                                            <icon-park-eye theme="outline" size="14" />
                                        </div>
                                        <div class="text-white cursor-pointer rounded-full p-2 bg-neutral-500" @click.stop="removeMedia">
                                            <icon-park-delete theme="outline" size="14" />
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <!-- 未上传媒体时的上传提示 -->
                            <template v-if="fileList.length === 0">
                                <component 
                                    v-if="iconComponent" 
                                    :is="iconComponent" 
                                    :class="iconColor" 
                                    :size="iconSize" 
                                    class="mb-2"
                                />
                                <icon-upload v-else class="text-white mb-4" :size="iconSize" />
                                <span class="text-xs text-white/80" :class="style">{{ placeholder }}</span>
                            </template>
                        </div>
                        <div v-else>
                            <a-spin :size="32" />
                        </div>
                    </div>
                    <template #content>
                        <!-- 悬浮菜单 -->
                        <Hover
                            :custom-class="popupClass"
                            :accept="accept"
                            :menu-items="menuItems"
                            :is-upload="isUpload"
                            :mini="mini"
                            :type="type"
                            :folder="folder"
                            @update:file="handleLocalFileSelected"
                            @update:media="showMediaCenter"
                            @update:loading="(val: boolean) => loading = val"
                        />
                    </template>
                </a-popover>
            </template>
        </a-upload>

        <!-- 图片预览 -->
        <a-image-preview
            v-if="previewVisible && type === 'image'"
            v-model:visible="previewVisible"
            :src="fileList[0]?.url"
        />
    </div>
</template>

<script lang="ts">
import { defineComponent, PropType } from 'vue';
import { Message } from '@arco-design/web-vue';
import { IconUpload } from '@arco-design/web-vue/es/icon';
import { Upload, PreviewOpen, Delete } from '@icon-park/vue-next';
import Hover from './hover.vue';

interface FileItem {
    id: number;
    name: string;
    url: string;
    file: File | null;
}

interface MenuItem {
    label: string;
    icon: any;
    action: string;
}

export default defineComponent({
    name: 'Upload',
    
    components: {
        'icon-park-upload': Upload,
        'icon-park-eye': PreviewOpen,
        'icon-park-delete': Delete,
        IconUpload,
        Hover,
    },
    
    props: {
        placeholder: {
            type: String,
            default: 'Upload media'
        },
        value: {
            type: Array,
            default: () => []
        },
        height: {
            type: String,
            default: 'auto'
        },
        width: {
            type: String,
            default: '100%'
        },
        iconComponent: {
            type: null,
            default: null
        },
        iconSize: {
            type: Number,
            default: 32
        },
        iconColor: {
            type: String,
            default: 'text-white'
        },
        accept: {
            type: String,
            default: 'image/*'
        },
        style: {
            type: String,
            default: ''
        },
        popup: {
            type: String,
            default: '260px'
        },
        menuItems: {
            type: Array as PropType<MenuItem[]>,
            default: () => []
        },
        isUpload: {
            type: Boolean,
            default: false
        },
        mini: {
            type: Boolean,
            default: false
        },
        type: {
            type: String,
            default: 'image'
        },
        borderColor: {
            type: String,
            default: 'border-gray-200'
        },
        url: {
            type: String,
            default: ''
        },
        folder: {
            type: String,
            default: '3'
        }
    },
    
    emits: ['update:value', 'upload'],
    
    data() {
        return {
            fileList: [] as FileItem[],
            mediaCentreVisible: false,
            loading: false,
            previewVisible: false
        }
    },

    setup(props) {
        const popupClass = 'absolute top-0 left-1/2 -translate-x-1/2 !max-w-[' + props.popup + '] !w-[' + props.popup + ']'
        return {
            popupClass
        }
    },
    
    watch: {
        value: {
            handler(newVal) {
                if (newVal && newVal.length > 0) {
                    this.fileList = [...newVal];
                } else {
                    this.fileList = [];
                }
            },
            immediate: true
        },
        url: {
            handler(newVal) {
                if (newVal && this.fileList.length === 0) {
                    this.fileList = [{
                        id: Date.now(),
                        name: newVal.split('/').pop() || '',
                        url: newVal,
                        file: null
                    }];
                }
            },
            immediate: true
        }
    },
    
    methods: {
        handleLocalFileSelected({ url, file }: { url: string, file: File }): void {
            this.fileList = [{
                id: Date.now(),
                name: file.name,
                url: url,
                file: file
            }];
            this.emitChange();
            Message.success('Media uploaded successfully');
        },
        
        showMediaCenter(): void {
            this.mediaCentreVisible = true;
        },
        
        removeMedia(): void {
            this.fileList = [];
            this.emitChange();
            Message.success('Media removed');
        },
        
        emitChange(): void {
            this.$emit('update:value', this.fileList);
            this.$emit('upload', this.fileList);
        },

        handleMediaData(media: { id: number, url: string, name: string }[]): void {
            if (media.length === 0) return;
            
            this.fileList = media.map(item => ({
                id: item.id,
                name: item.name,
                url: item.url,
                file: null
            }));
            
            this.emitChange();
        },

        previewMedia(): void {
            this.previewVisible = true;
        }
    }
});
</script>